package com.bsj.media.media.resample.basic;

import com.bsj.media.media.resample.resamplerState;

public class resamplerBasicInterpolateDouble extends resamplerBasic {

	@Override
	public int getType() {
		return 1;
	}

	@Override
	public int resampler_basic_func(resamplerState st, int channel_index, float[] in, final int offset_in, int in_len, float[] out,
									int out_len) {
		final int N = st.filt_len;
		int out_sample = 0;
		int last_sample = st.last_sample[channel_index];
		int samp_frac_num = st.samp_frac_num[channel_index] & 0xffffffff;
		final int out_stride = st.out_stride;
		final int int_advance = st.int_advance;
		final int frac_advance = st.frac_advance;
		final int den_rate = st.den_rate;
		float sum;

		while (!(last_sample >= in_len || out_sample >= out_len)) {
			final int offset = (int) (samp_frac_num * st.oversample / st.den_rate);

			final float frac = ((float) ((samp_frac_num * st.oversample) % st.den_rate)) / st.den_rate;

			float[] interp = new float[4];

			double[] accum = { 0, 0, 0, 0 };

			int j = 0;
			for (j = 0; j < N; j++) {
				final double curr_in = in[offset_in+j + last_sample];
				accum[0] += MULT16_16((float) curr_in, st.sinc_table[(int) (4 + (j + 1) * st.oversample - offset - 2)]);
				accum[1] += MULT16_16((float) curr_in, st.sinc_table[(int) (4 + (j + 1) * st.oversample - offset - 1)]);
				accum[2] += MULT16_16((float) curr_in, st.sinc_table[(int) (4 + (j + 1) * st.oversample - offset)]);
				accum[3] += MULT16_16((float) curr_in, st.sinc_table[(int) (4 + (j + 1) * st.oversample - offset + 1)]);
			}

			cubic_coef(frac, interp);
			sum = MULT16_32_Q15(interp[0], (float) accum[0]) + MULT16_32_Q15(interp[1], (float) accum[1])
					+ MULT16_32_Q15(interp[2], (float) accum[2]) + MULT16_32_Q15(interp[3], (float) accum[3]);

			// out[out_stride * out_sample++] = PSHR32(sum,15);
			out[out_stride * out_sample++] = sum;
			last_sample += int_advance;
			samp_frac_num += frac_advance;
			if (samp_frac_num >= den_rate) {
				samp_frac_num -= den_rate;
				last_sample++;
			}
		}

		st.last_sample[channel_index] = last_sample;
		st.samp_frac_num[channel_index] = samp_frac_num;
		return out_sample;
	}

}
